﻿#include "thread.h"

#include <chrono>

#ifdef BREAKING_OS_WINDOWS
#include <windows.h>
#else
#include <unistd.h>
#include <sys/syscall.h>
#define gettid() syscall(__NR_gettid)
#endif //

namespace breaking
{
	thread::thread() :m_id(0), m_running(false), m_stop_requested(false)
	{
	}

	thread::~thread()
	{
	}

	bool thread::activate()
	{
		{
			std::lock_guard<std::mutex> lock(m_mtx);
			if (!m_running)
			{
				m_running = true;
				m_stop_requested = false;
				m_thread_obj = std::thread([this]()
					{
						m_id = _sys_thread_id();
						this->run();
						m_running = false;
					}
				);
			}
		}

		return m_running;
	}

	void thread::stop()
	{
		{
			std::lock_guard<std::mutex> lock(m_mtx);
			if (m_running)
			{
				m_stop_requested = true;
			}
		}

		join();
	}

	void thread::join()
	{
		if (m_thread_obj.joinable())
		{
			m_thread_obj.join();
		}
	}

	void thread::sleep(uint32_t msecs)
	{
		std::this_thread::sleep_for(std::chrono::milliseconds(msecs));
	}

	bool thread::is_stop_requested() const
	{
		return m_stop_requested;
	}

	int32_t thread::get_id()const
	{
		return m_id;
	}

	int32_t thread::_sys_thread_id() const
	{
#ifdef BREAKING_OS_WINDOWS
		return GetCurrentThreadId();
#else
		return gettid();
#endif //
	}
}